home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------------
-
- apputil.c
-
- This reusable module contains utility routines for finding and running helper
- applications.
-
- Adapted from DTS sample code "SignatureToApp" and "LaunchWithDoc"
-
- ----------------------------------------------------------------------------*/
-
- #include <string.h>
- #include <stdio.h>
-
- #include "def.h"
- #include "apputil.h"
- #include "memutil.h"
- #include "fileutil.h"
- #include "strutil.h"
- #include "resutil.h"
-
-
-
- /*----------------------------------------------------------------------------
- FindRunningAppBySignature
-
- Find a running app given its signature.
-
- Entry: sig = signature of app.
-
- Exit: function result = error code.
- = procNotFound if not running.
- *fSpec = file spec of app.
- *psn = process serial number of running app.
- ----------------------------------------------------------------------------*/
-
- static OSErr FindRunningAppBySignature (OSType sig, FSSpec *fSpec,
- ProcessSerialNumber *psn)
- {
- OSErr err = noErr;
- ProcessInfoRec info;
-
- psn->highLongOfPSN = 0;
- psn->lowLongOfPSN = kNoProcess;
- while (true) {
- err = GetNextProcess(psn);
- if (err != noErr) return err;
- info.processInfoLength = sizeof(info);
- info.processName = nil;
- info.processAppSpec = fSpec;
- err = GetProcessInformation(psn, &info);
- if (err != noErr) return err;
- if (info.processSignature == sig) return noErr;
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- VolHasDesktopDB
-
- Check to see if a volume supports the new desktop database.
-
- Entry: vRefNum = vol ref num of volumn
-
- Exit: function result = error code.
- *hasDesktop = true if volume has the new desktop database.
- ----------------------------------------------------------------------------*/
-
- static OSErr VolHasDesktopDB (short vRefNum, Boolean *hasDesktop)
- {
- HParamBlockRec pb;
- GetVolParmsInfoBuffer info;
- OSErr err = noErr;
-
- pb.ioParam.ioCompletion = nil;
- pb.ioParam.ioNamePtr = nil;
- pb.ioParam.ioVRefNum = vRefNum;
- pb.ioParam.ioBuffer = (Ptr)&info;
- pb.ioParam.ioReqCount = sizeof(info);
- err = PBHGetVolParmsSync(&pb);
- *hasDesktop = err == noErr && (info.vMAttrib & (1L << bHasDesktopMgr)) != 0;
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- FindAppOnVolume
-
- Find an application on a volume.
-
- Entry: sig = application signature.
- vRefNum = vol ref num
-
- Exit: function result = error code
- = afpItemNotFound if app not found on vol.
- *file = file spec for application on volume.
- ----------------------------------------------------------------------------*/
-
- static OSErr FindAppOnVolume (OSType sig, short vRefNum, FSSpec *file)
- {
- DTPBRec pb;
- OSErr err = noErr;
- short ioDTRefNum, i;
- FInfo fInfo;
- FSSpec candidate;
- unsigned long lastModDateTime, maxLastModDateTime;
-
- memset(&pb, 0, sizeof(DTPBRec));
- pb.ioCompletion = nil;
- pb.ioVRefNum = vRefNum;
- pb.ioNamePtr = nil;
- err = PBDTGetPath(&pb);
- if (err != noErr) return err;
- ioDTRefNum = pb.ioDTRefNum;
-
- memset(&pb, 0, sizeof(DTPBRec));
- pb.ioCompletion = nil;
- pb.ioIndex = 0;
- pb.ioFileCreator = sig;
- pb.ioNamePtr = file->name;
- pb.ioDTRefNum = ioDTRefNum;
- err = PBDTGetAPPLSync(&pb);
-
- if (err == fnfErr || err == paramErr) return afpItemNotFound;
- if (err != noErr) return err;
-
- file->vRefNum = vRefNum;
- file->parID = pb.ioAPPLParID;
-
- err = FSpGetFInfo(file, &fInfo);
- if (err == noErr) return noErr;
-
- i = 1;
- maxLastModDateTime = 0;
- while (true) {
- memset(&pb, 0, sizeof(DTPBRec));
- pb.ioCompletion = nil;
- pb.ioIndex = i;
- pb.ioFileCreator = sig;
- pb.ioNamePtr = candidate.name;
- pb.ioDTRefNum = ioDTRefNum;
- err = PBDTGetAPPLSync(&pb);
- if (err != noErr) break;
- candidate.vRefNum = vRefNum;
- candidate.parID = pb.ioAPPLParID;
- err = GetLastModDateTime(file, &lastModDateTime);
- if (err == noErr) {
- if (lastModDateTime > maxLastModDateTime) {
- maxLastModDateTime = lastModDateTime;
- *file = candidate;
- }
- }
- i++;
- }
-
- return maxLastModDateTime > 0 ? noErr : afpItemNotFound;
- }
-
-
-
- /*----------------------------------------------------------------------------
- FindAppFromSig
-
- Find an application given its signature.
-
- Entry: sig = application signature
-
- Entry: running = nil to skip check for running app and just do
- a desktop database search for the disk file.
-
- Exit: function result = error code.
- = fnfErr if app not found
- *fSpec = file spec of application.
- *running = true if app is running.
- *psn = process serial number of app if running.
- ----------------------------------------------------------------------------*/
-
- OSErr FindAppFromSig (OSType sig, FSSpec *fSpec, Boolean *running,
- ProcessSerialNumber *psn)
- {
- OSErr err = noErr;
- short sysVRefNum, vRefNum, index;
- Boolean hasDesktopDB;
-
- if (running != nil) {
- err = FindRunningAppBySignature(sig, fSpec, psn);
- *running = true;
- if (err == noErr) return noErr;
- *running = false;
- if (err != procNotFound) return err;
- }
- err = GetSysVolume(&sysVRefNum);
- if (err != noErr) return err;
- vRefNum = sysVRefNum;
- index = 0;
- while (true) {
- if (index == 0 || vRefNum != sysVRefNum) {
- err = VolHasDesktopDB(vRefNum, &hasDesktopDB);
- if (err != noErr) return err;
- if (hasDesktopDB) {
- err = FindAppOnVolume(sig, vRefNum, fSpec);
- if (err != afpItemNotFound) return err;
- }
- }
- index++;
- err = GetIndVolume(index, &vRefNum);
- if (err == nsvErr) return fnfErr;
- if (err != noErr) return err;
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- FindAppNameFromSig
-
- Find an application name given its signature.
-
- Entry: sig = application signature
-
- Exit: function result = error code.
- = fnfErr if app not found
- name = application name.
- ----------------------------------------------------------------------------*/
-
- OSErr FindAppNameFromSig (OSType sig, StringPtr name)
- {
- FSSpec fSpec;
- OSErr err = noErr;
-
- err = FindAppFromSig(sig, &fSpec, nil, nil);
- if (err != noErr) return err;
- CopyPascalString(name, fSpec.name);
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- LaunchAppWithDoc
-
- Launch an application with an initial open document event.
-
- Entry: running = true if application is running, in which case
- it is sent the odoc event.
- appSpec = file spec of application.
- *psn = process serial number of app if it is running.
- docSpec = file spec of document.
- launchFileFlags = file flags.
- launchControlFlags = control flags.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr LaunchAppWithDoc (Boolean running, FSSpec *appSpec, ProcessSerialNumber *psn,
- FSSpec *docSpec, unsigned short launchFileFlags, unsigned short launchControlFlags)
- {
- ProcessSerialNumber thePSN;
- LaunchParamBlockRec launchThis;
- AEDesc target = {0, nil};
- AEDesc docDesc = {0, nil};
- AEDesc launchDesc = {0, nil};
- AEDescList theList = {0, nil};
- AliasHandle withThis = nil;
- AppleEvent theEvent = {0, nil};
- AppleEvent theReply = {0, nil};
- OSErr err = noErr;
- Boolean autoParamValue = false;
-
- if (running) thePSN = *psn;
- err = AECreateDesc(typeProcessSerialNumber, &thePSN, sizeof(thePSN), &target);
- if (err != noErr) goto exit;
- err = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &target,
- kAutoGenerateReturnID, kAnyTransactionID, &theEvent);
- if (err != noErr) goto exit;
- err = AECreateList(nil, 0, false, &theList);
- if (err != noErr) goto exit;
- err = NewAlias(nil, docSpec, &withThis);
- if (err != noErr) goto exit;
- MyHLock(withThis);
- err = AECreateDesc(typeAlias, (Ptr)*withThis, MyGetHandleSize(withThis),
- &docDesc);
- if (err != noErr) goto exit;
- MyHUnlock(withThis);
- err = AEPutDesc(&theList, 0, &docDesc);
- if (err != noErr) goto exit;
- err = AEPutParamDesc(&theEvent, keyDirectObject, &theList);
- if (err != noErr) goto exit;
- if (running) {
- err = AESend(&theEvent, &theReply, kAENoReply, kAENormalPriority, kNoTimeOut,
- nil, nil);
- if (err != noErr) goto exit;
- if ((launchControlFlags & launchDontSwitch) == 0) {
- err = SetFrontProcess(psn);
- if (err != noErr) goto exit;
- }
- } else {
- err = AECoerceDesc(&theEvent, typeAppParameters, &launchDesc);
- if (err != noErr) goto exit;
- MyHLock(theEvent.dataHandle);
- launchThis.launchAppSpec = appSpec;
- launchThis.launchAppParameters = (AppParametersPtr)*launchDesc.dataHandle;
- launchThis.launchBlockID = extendedBlock;
- launchThis.launchEPBLength = extendedBlockLen;
- launchThis.launchFileFlags = launchFileFlags;
- launchThis.launchControlFlags = launchControlFlags;
- err = LaunchApplication(&launchThis);
- }
-
- exit:
-
- MyDisposeHandle(withThis);
- if (target.dataHandle != nil) AEDisposeDesc(&target);
- if (docDesc.dataHandle != nil) AEDisposeDesc(&docDesc);
- if (launchDesc.dataHandle != nil) AEDisposeDesc(&launchDesc);
- if (theList.dataHandle != nil) AEDisposeDesc(&theList);
- if (theEvent.dataHandle != nil) AEDisposeDesc(&theEvent);
- if (theReply.dataHandle != nil) AEDisposeDesc(&theReply);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- LaunchAppWithEventAndString
-
- Launch an application with an initial event with a string parameter.
-
- Entry: running = true if application is running, in which case
- it is sent the odoc event.
- appSpec = file spec of application.
- *psn = process serial number of app if it is running.
- eventClass = event class.
- eventID = event id.
- keyword = parameter keyword (keyDirectObject if string is the
- direct object).
- str = the string parameter for the event.
- launchFileFlags = file flags.
- launchControlFlags = control flags.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr LaunchAppWithEventAndString (Boolean running, FSSpec *appSpec, ProcessSerialNumber *psn,
- OSType eventClass, OSType eventID, OSType keyword, char *str,
- unsigned short launchFileFlags, unsigned short launchControlFlags)
- {
- ProcessSerialNumber thePSN;
- LaunchParamBlockRec launchThis;
- AEDesc target = {0, nil};
- AEDesc stringDesc = {0, nil};
- AEDesc launchDesc = {0, nil};
- AppleEvent theEvent = {0, nil};
- AppleEvent theReply = {0, nil};
- OSErr err = noErr;
- Boolean autoParamValue = false;
-
- if (running) thePSN = *psn;
- err = AECreateDesc(typeProcessSerialNumber, &thePSN, sizeof(thePSN), &target);
- if (err != noErr) goto exit;
- err = AECreateAppleEvent(eventClass, eventID, &target,
- kAutoGenerateReturnID, kAnyTransactionID, &theEvent);
- if (err != noErr) goto exit;
- err = AECreateDesc(typeChar, str, strlen(str), &stringDesc);
- if (err != noErr) goto exit;
- err = AEPutParamDesc(&theEvent, keyword, &stringDesc);
- if (err != noErr) goto exit;
- if (running) {
- err = AESend(&theEvent, &theReply, kAENoReply, kAENormalPriority, kNoTimeOut,
- nil, nil);
- if (err != noErr) goto exit;
- if ((launchControlFlags & launchDontSwitch) == 0) {
- err = SetFrontProcess(psn);
- if (err != noErr) goto exit;
- }
- } else {
- err = AECoerceDesc(&theEvent, typeAppParameters, &launchDesc);
- if (err != noErr) goto exit;
- MyHLock(theEvent.dataHandle);
- launchThis.launchAppSpec = appSpec;
- launchThis.launchAppParameters = (AppParametersPtr)*launchDesc.dataHandle;
- launchThis.launchBlockID = extendedBlock;
- launchThis.launchEPBLength = extendedBlockLen;
- launchThis.launchFileFlags = launchFileFlags;
- launchThis.launchControlFlags = launchControlFlags;
- err = LaunchApplication(&launchThis);
- }
-
- exit:
-
- if (target.dataHandle != nil) AEDisposeDesc(&target);
- if (stringDesc.dataHandle != nil) AEDisposeDesc(&stringDesc);
- if (launchDesc.dataHandle != nil) AEDisposeDesc(&launchDesc);
- if (theEvent.dataHandle != nil) AEDisposeDesc(&theEvent);
- if (theReply.dataHandle != nil) AEDisposeDesc(&theReply);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- AppCanOpenFileType
-
- Check to see if an application can open a given type of file.
-
- Entry: pb = pointer to file info param block for a file of type
- 'APPL' or 'adrp'.
- fileType = file type.
-
- Exit: function result = true if app can open files of the specified type.
- ----------------------------------------------------------------------------*/
-
- Boolean AppCanOpenFileType (CInfoPBPtr pb, OSType fileType)
- {
- FSSpec fSpec;
- short refNum = 0;
- short i;
- Handle frefHandle;
- Boolean targetIsFolder, wasAliased;
- OSErr err = noErr;
- FInfo fndrInfo;
-
- fSpec.vRefNum = pb->hFileInfo.ioVRefNum;
- fSpec.parID = pb->hFileInfo.ioFlParID,
- CopyPascalString(fSpec.name, pb->hFileInfo.ioNamePtr);
-
- if (pb->hFileInfo.ioFlFndrInfo.fdType == 'adrp') {
- err = ResolveAliasFile(&fSpec, true, &targetIsFolder, &wasAliased);
- if (err != noErr || targetIsFolder) return false;
- err = FSpGetFInfo(&fSpec, &fndrInfo);
- if (err != noErr) return false;
- if (fndrInfo.fdType != 'APPL') return false;
- }
-
- SetResLoad(false);
- err = MyFSpOpenResFile(&fSpec, fsRdPerm, &refNum);
- SetResLoad(true);
- if (err != noErr) goto exit;
-
- for (i = 1; ; i++) {
- err = MyGet1IndResource('FREF', i, &frefHandle);
- if (err != noErr) goto exit;
- if (**(OSType**)frefHandle == fileType) break;
- if (**(OSType**)frefHandle == '****') break;
- }
-
- MyCloseResFile(refNum);
- return true;
-
- exit:
-
- if (refNum != 0) MyCloseResFile(refNum);
- return false;
- }
-
-
-
- /*----------------------------------------------------------------------------
- FileIsApplication
-
- Check to see if a file is an application or an alias to an application.
-
- Entry: pb = pointer to file info param block for a file of type
- 'APPL' or 'adrp'.
-
- Exit: function result = true if application.
- ----------------------------------------------------------------------------*/
-
- Boolean FileIsApplication (CInfoPBPtr pb)
- {
- FSSpec fSpec;
- Boolean targetIsFolder, wasAliased;
- OSErr err = noErr;
- FInfo fndrInfo;
-
- if (pb->hFileInfo.ioFlFndrInfo.fdType == 'APPL') return true;
- if (pb->hFileInfo.ioFlFndrInfo.fdType != 'adrp') return false;
- fSpec.vRefNum = pb->hFileInfo.ioVRefNum;
- fSpec.parID = pb->hFileInfo.ioFlParID,
- CopyPascalString(fSpec.name, pb->hFileInfo.ioNamePtr);
- err = ResolveAliasFile(&fSpec, true, &targetIsFolder, &wasAliased);
- if (err != noErr || targetIsFolder) return false;
- err = FSpGetFInfo(&fSpec, &fndrInfo);
- if (err != noErr) return false;
- return fndrInfo.fdType == 'APPL';
- }
-
-
-
- /*----------------------------------------------------------------------------
- GetAppVersionNumber
-
- Get the version number of an application..
-
- Entry: fSpec = pointer to application file spec.
-
- Exit: function result = error code.
- *versionNumber = version number.
- ----------------------------------------------------------------------------*/
-
- OSErr GetAppVersionNumber (FSSpec *fSpec, unsigned long *versionNumber)
- {
- OSErr err = noErr;
- short refNum = 0;
-
- SetResLoad(false);
- err = MyFSpOpenResFile(fSpec, fsRdPerm, &refNum);
- SetResLoad(true);
- if (err != noErr) goto exit;
- err = GetVersionNumber(versionNumber);
- if (err != noErr) goto exit;
- MyCloseResFile(refNum);
- return noErr;
-
- exit:
-
- if (refNum != 0) MyCloseResFile(refNum);
- return err;
- }
-